cmake_minimum_required(VERSION 3.12)

include(CheckIPOSupported)
check_ipo_supported(RESULT _IsIPOSupported)

if(_IsIPOSupported)
	message(STATUS "Enabled IPO optimization")
	set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

find_program(CCACHE_FOUND ccache)

if(CCACHE_FOUND)
	message(STATUS "Enabled ccache: ${CCACHE_FOUND}")
	set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_FOUND})
	set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_FOUND}) # Less useful to do it for linking, see edit2
endif()

set(CMAKE_POLICY_VERSION_MINIMUM 3.5)

# set the project name
project(HMCL
	VERSION 1.2.7
	LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0.0")
	add_compile_options(-Wno-calloc-transposed-args) # fix gcc-14 error for zip
endif()

# 为MSVC设置静态链接
if(MSVC)
	add_compile_options(/W4 /MT)
endif()

set(SPDLOG_USE_STD_FORMAT ON)

add_subdirectory(
	3rd/toml11
	EXCLUDE_FROM_ALL)
add_subdirectory(
	3rd/yaml-cpp
	EXCLUDE_FROM_ALL)
add_subdirectory(
	3rd/spdlog
	EXCLUDE_FROM_ALL)
add_subdirectory(
	3rd/dbg-macro
	EXCLUDE_FROM_ALL)
add_subdirectory(
	3rd/zip
	EXCLUDE_FROM_ALL)
add_subdirectory(
	3rd/cxxopts
	EXCLUDE_FROM_ALL)

add_executable(${PROJECT_NAME} src/HMCL-r.cc)

target_include_directories(${PROJECT_NAME}
	PRIVATE 3rd/boost/include
	PRIVATE 3rd/cppitertools/cppitertools)

target_link_libraries(${PROJECT_NAME}
	spdlog::spdlog $<$<BOOL:${MINGW}>:ws2_32>
	dbg_macro
	toml11::toml11
	yaml-cpp::yaml-cpp
	zip::zip
	cxxopts::cxxopts)

if(NOT CMAKE_BUILD_TYPE MATCHES "Deb" AND NOT MSVC)
	# strip release
	target_link_libraries(${PROJECT_NAME} -s)
endif()

# 设置MSVC编译器的特殊处理
if(MSVC)
	# 手动适配clangd提示，不保真... 不知道会不会有什么奇怪的问题，出问题可以翻找一下cmake的缓存看看里面存了什么
	if(CMAKE_C_COMPILER MATCHES "cl.exe")
		get_filename_component(VC_INCLUDE_DIR ${CMAKE_C_COMPILER} DIRECTORY)
		get_filename_component(VC_INCLUDE_DIR ${VC_INCLUDE_DIR} DIRECTORY)
		get_filename_component(VC_INCLUDE_DIR ${VC_INCLUDE_DIR} DIRECTORY)
		get_filename_component(VC_INCLUDE_DIR ${VC_INCLUDE_DIR} DIRECTORY)

		set(DIASDK_DIR "${VC_INCLUDE_DIR}")
		get_filename_component(DIASDK_DIR ${DIASDK_DIR} DIRECTORY)
		get_filename_component(DIASDK_DIR ${DIASDK_DIR} DIRECTORY)
		get_filename_component(DIASDK_DIR ${DIASDK_DIR} DIRECTORY)
		get_filename_component(DIASDK_DIR ${DIASDK_DIR} DIRECTORY)
		set(DIASDK_DIR "${DIASDK_DIR}/DIA SDK/include")
		message(STATUS "DIASDK_DIR: ${DIASDK_DIR}")

		set(VC_INCLUDE_DIR "${VC_INCLUDE_DIR}/include")
		message(STATUS "VC_INCLUDE_DIR: ${VC_INCLUDE_DIR}")

		include_directories(
			BEFORE SYSTEM
			"${DIASDK_DIR}"
			"${VC_INCLUDE_DIR}"
		)
	endif()

	if(DEFINED CMAKE_MT)
		get_filename_component(WINDOWS_KITS_10_DIR ${CMAKE_MT} DIRECTORY)
		get_filename_component(_PLATFORM ${WINDOWS_KITS_10_DIR} NAME)
		get_filename_component(WINDOWS_KITS_10_DIR ${WINDOWS_KITS_10_DIR} DIRECTORY)
		get_filename_component(_VERSION ${WINDOWS_KITS_10_DIR} NAME)
		get_filename_component(WINDOWS_KITS_10_DIR ${WINDOWS_KITS_10_DIR} DIRECTORY)
		get_filename_component(WINDOWS_KITS_10_DIR ${WINDOWS_KITS_10_DIR} DIRECTORY)

		message(STATUS "WINDOWS_KITS_10_DIR: ${WINDOWS_KITS_10_DIR}")
		include_directories(
			BEFORE SYSTEM
			"${WINDOWS_KITS_10_DIR}/include/${_VERSION}/um"
			"${WINDOWS_KITS_10_DIR}/include/${_VERSION}/ucrt"
			"${WINDOWS_KITS_10_DIR}/include/${_VERSION}/shared"
			"${WINDOWS_KITS_10_DIR}/include/${_VERSION}/winrt"
		)
	endif()
endif()

if(WIN32)
	# linux cmake cant recognize .rc file
	# NOTE: Use MSVC CMake instead of mingw version if build failed here
	target_sources(${PROJECT_NAME} PRIVATE src/icon.rc)

	# msys2 mingw32 link static stdc++ on windows
	if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
		target_link_libraries(${PROJECT_NAME} -static gcc stdc++ pthread -dynamic)
	elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
		target_link_libraries(${PROJECT_NAME} -Wl,-allow-multiple-definition) # for force fix allow Clang and GCC ABI error (duplicate section has different size). See https://doc.magnum.graphics/magnum/platforms-windows.html#platform-windows-troubleshooting-duplicate-section-has-different-size
		target_link_libraries(${PROJECT_NAME} -static c++ pthread -dynamic)
	elseif(MSVC)
		target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
	endif()

	if(NOT CMAKE_BUILD_TYPE MATCHES "Deb")
		if(MSVC)
			target_link_options(${PROJECT_NAME} PRIVATE /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup)
		else()
			target_link_options(${PROJECT_NAME} PRIVATE -mwindows) # -mconsole
		endif()
	endif()

	add_library(Registry STATIC 3rd/Registry/Registry/src/Registry.cpp)
	include_directories(3rd/Registry/Registry/include)
	target_link_libraries(${PROJECT_NAME} Registry)
endif()

message(STATUS "Default Config File Source Embeded.")
file(READ src/default.conf __CONFIG_TOML__)
configure_file(
	src/get_conf.h.in
	${PROJECT_SOURCE_DIR}/src/get_conf.h
	@ONLY
)

# Copy executable after both are built
add_custom_command(
	TARGET ${PROJECT_NAME} POST_BUILD
	COMMAND ${CMAKE_COMMAND} -E copy
	${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:${PROJECT_NAME}>
	${CMAKE_CURRENT_SOURCE_DIR}/
	COMMENT "Copying $<TARGET_FILE_NAME:${PROJECT_NAME}> to source directory"
)

# Include CPack configuration
set(CPACK_PACKAGE_NAME ${PROJECT_NAME}_Wrapper)
set(CPACK_PACKAGE_VENDOR hibays)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LoveOffices Application Package")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME}_Wrapper)

# Set the generator to ZIP (you can also use NSIS, WIX, etc. for installers)
set(CPACK_GENERATOR ZIP)

# For Windows, you might want to include these additional settings
if(WIN32)
	set(CPACK_PACKAGE_ICON src/micon.ico)
	set(CPACK_NSIS_MUI_ICON src/micon.ico)
	set(CPACK_NSIS_MUI_UNIICON src/micon.ico)
	set(CPACK_NSIS_INSTALLED_ICON_NAME ${PROJECT_NAME}.exe)
	set(CPACK_NSIS_DISPLAY_NAME ${PROJECT_NAME})
	set(CPACK_NSIS_MODIFY_PATH ON)
endif()

# Include CPack module (must be after all CPACK_* variables are set)
include(CPack)

# Install all required files
install(
	TARGETS ${PROJECT_NAME}
	RUNTIME DESTINATION .
)

install(
	DIRECTORY hmcl-rt/
	DESTINATION hmcl-rt
)

install(DIRECTORY
	java/
	DESTINATION java
)

install(FILES
	config.toml
	DESTINATION .
)

add_custom_target(make_package
	COMMAND ${CMAKE_CPACK_COMMAND}
	DEPENDS ${PROJECT_NAME}
	COMMENT "Creating package..."
)
